﻿using eslib.nnp5.layers;
using System;
using System.Threading.Tasks;

namespace eslib.nnp5
{
    /// <summary>
    /// 微型FF协议App基类
    /// </summary>
    public abstract class MicroFFAppBase : IAppBase
    {
        /// <summary>
        /// 传输层
        /// </summary>
        public MicroFFTransportLayer transport { get; private set; } = null;


        /// <summary>
        /// AppUser绑定的对象(可选使用)
        /// </summary>
        public Object BindingObject { get; set; } = null;




        /// <summary>
        /// 
        /// </summary>
        /// <param name="connector"></param>
        public MicroFFAppBase(Connector connector)
        {
            Reset();   //重置队列
            Connected = true;       //已连接

            this.transport = new MicroFFTransportLayer(connector);
            this.transport.NewTransportLayerDataEvent += Transport_NewTransportLayerDataEvent;

            connector.DisconnectEvent += Connector_DisconnectEvent;     //断开时自动释放连接器            
        }



        /// <summary>
        /// 连接标记，断开后返回false
        /// </summary>
        public bool Connected
        {
            get
            {
                lock (this)
                {
                    return connected;
                }
            }
            set
            {
                lock (this)
                {
                    connected = value;
                }
            }
        }
        bool connected;




        public void Close()
        {
            //引发断开连接事件
            Connector_DisconnectEvent(transport.connector, "主动Close");
        }





        private void Transport_NewTransportLayerDataEvent(byte[] buffer)
        {
            //异步调用事件
            Task.Run(() =>
            {
                NewPKGEvent(buffer);
            });
        }


        private void Connector_DisconnectEvent(Connector connector, string message)
        {
            //连接断开
            Connected = false;
            Reset();       //重置队列

            //释放连接器
            try
            {
                transport.connector.close();
            }
            catch { }

            //通知上层
            Task.Run(() =>
            {
                DisconnectEvent(connector, message);
            });
        }




        public void Reset()
        {
            if (transport != null)
                transport.Reset();
        }


        /// <summary>
        /// 发送数据包
        /// </summary>
        /// <param name="pkg"></param>
        public virtual void SendPkg(IPackage pkg)
        {
            transport.sendData(pkg.GetBuffer());
        }


        /// <summary>
        /// 发送数据包
        /// </summary>
        /// <param name="pkg"></param>
        public virtual void SendPkg(byte[] pkg)
        {
            transport.sendData(pkg);
        }


        #region 抽象方法

        /// <summary>
        /// [异步事件]连接断开处理
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="message"></param>
        public abstract void DisconnectEvent(Connector connector, string message);


        /// <summary>
        /// [异步事件]新数据包处理
        /// </summary>
        /// <param name="oriBuffer">原始数据</param>
        public abstract void NewPKGEvent(byte[] oriBuffer);


        #endregion
    }

}